/************************************************************************
  DISCLAIMER:
  This software was produced by the National Institute of Standards
  and Technology (NIST), an agency of the U.S. government, and by statute
  is not subject to copyright in the United States.  Recipients of this
  software assume all responsibility associated with its operation,
  modification, maintenance, and subsequent redistribution.

  See NIST Administration Manual 4.09.07 b and Appendix I.
************************************************************************/

#include <string.h>  // for strlen, strcpy, strcat
#include <stdio.h>   // for fopen, etc.
#include <stdlib.h>  // for exit
#include "dmis.hh"   // for dmisStatement

namespace NDTS {

extern int numErrors;                               // in parser library
extern int numWarnings;                             // in parser library
extern std::list<dmisStatement *> dmisStms;         // in parser library
extern inputFile * tree;                            // in parser library
void parseDmis(char * fileName);                    // in parser library
void resetParser();                                 // in parser library
} // namespace NDTS

namespace NDTU {
  using namespace NDTS;

void parseManyFiles(char * fileNameFile);           // in this file
void parseOneFile(char * dmiName, bool printTree);  // in this file
int runParser(int argc, char * argv[]);             // in this file

/********************************************************************/

/* runParser

Returned Value: int
This returns 1 if the parser is called incorrectly or the input or
output file cannot be opened. Otherwise, it returns 0.

Called By: command invocation by a user

This checks the arguments.

If the input file ends in .dmi (upper or lower case, or mixed), this
calls parseOneFile. Otherwise, it calls parseManyFiles.

*/

int runParser(
 int argc,
 char * argv[])
{
  int k; // length of file name
  char * filename;

  if (argc != 2)
    {
      fprintf(stderr, "Usage: %s <input file name>\n", argv[0]);
      exit(1);
    }
  filename = argv[1];
  k = strlen(filename);
  if ((filename[k-4] == '.') &&
      ((filename[k-3] == 'd') || (filename[k-3] == 'D')) &&
      ((filename[k-2] == 'm') || (filename[k-2] == 'M')) &&
      ((filename[k-1] == 'i') || (filename[k-1] == 'I')))
    { // argv[1] is a DMIS input file name
      parseOneFile(argv[1], true);
    }
  else
    { // argv[1] is the name of a file containing DMIS input file names
      parseManyFiles(argv[1]);
    }
  return 0;
}

/********************************************************************/

/* parseManyFiles

Returned Value: none

Called By: runParser

This expects that the file whose name is fileNameFile will contain the
names of a number of DMIS input files.

For each file listed in the fileNameFile, this calls parseOneFile to
parse the file.

*/

void parseManyFiles(  /* ARGUMENTS                                     */
 char * fileNameFile) /* name of file containing DMIS input file names */
{
  FILE * fileList;
  static char fileName[256];
  int nameLength;

  fileList = fopen(fileNameFile, "r");
  if (fileList == 0)
    {
      fprintf(stderr, "unable to open file %s for reading\n",
              fileNameFile);
      exit(1);
    }
  while (fgets(fileName, 256, fileList))
    {
      nameLength = strlen(fileName);
      if (nameLength == 255)
	{
	  fprintf(stderr, "file name too long: %s\n", fileName);
	  exit(1);
        }
      while ((fileName[nameLength - 1] == 10) ||
             (fileName[nameLength - 1] == 13))
	{ // get rid of the end of line character(s)
	  fileName[nameLength - 1] = 0;
	  nameLength--;
	}
      if (strcmp((fileName + nameLength - 4), ".dmi"))
	{
	  fprintf(stderr, "file name does not end in .dmi: %s\n",
                  fileName);
	  exit(1);
	}
      printf("*****************************************\n\n");
      printf("%s\n\n", fileName);
      parseOneFile(fileName, false);
      dmisStms.clear();
      resetParser();
    }
  fclose(fileList);
}

/********************************************************************/

/* parseOneFile

Returned Value: none

Called By:
  runParser
  parseManyFiles

This parses one DMIS input file, prints error information, and,
if there are no errors and printTree is true, reprints the input file.

*/

void parseOneFile(
 char * dmiName,
 bool printTree)
{
  parseDmis(dmiName);
  printf("%d error%s\n", numErrors, ((numErrors == 1) ? "" : "s"));
  printf("%d warning%s\n", numWarnings, ((numWarnings == 1) ? "" : "s"));
  if ((numErrors == 0) && printTree)
    tree->printSelf();
}

/********************************************************************/

}  // namespace NDTU
